home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / cproto-3.0 / symbol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  2.4 KB  |  123 lines

  1. /* $Id: symbol.c 3.3 1993/05/26 01:36:41 cthuang Exp $
  2.  *
  3.  * Implements a symbol table abstract data type.
  4.  */
  5. #include <stdio.h>
  6. #include "cproto.h"
  7. #include "symbol.h"
  8.  
  9.  
  10. /* Create a symbol table.
  11.  * Return a pointer to the symbol table or NULL if an error occurs.
  12.  */
  13. SymbolTable *
  14. new_symbol_table ()
  15. {
  16.     SymbolTable *symtab;
  17.     int i;
  18.  
  19.     if ((symtab = (SymbolTable *)xmalloc(sizeof(SymbolTable))) != NULL) {
  20.     for (i = 0; i < SYM_MAX_HASH; ++i)
  21.         symtab->bucket[i] = NULL;
  22.     }
  23.     return symtab;
  24. }
  25.  
  26.  
  27. /* Free the memory allocated to the symbol table.
  28.  */
  29. void
  30. free_symbol_table (symtab)
  31. SymbolTable *symtab;
  32. {
  33.     int i;
  34.     Symbol *sym, *next;
  35.  
  36.     for (i = 0; i < SYM_MAX_HASH; ++i) {
  37.     sym = symtab->bucket[i];
  38.     while (sym != NULL) {
  39.         next = sym->next;
  40.         free(sym->name);
  41.         free(sym->value);
  42.         free(sym);
  43.         sym = next;
  44.     }
  45.     }
  46. }
  47.  
  48.  
  49. /* This is a simple hash function mapping a symbol name to a hash bucket. */
  50.  
  51. static unsigned
  52. hash (name)
  53. char *name;
  54. {
  55.     char *s;
  56.     unsigned h;
  57.  
  58.     h = 0;
  59.     s = name;
  60.     while (*s != '\0')
  61.     h = (h << 1) ^ *s++;
  62.     return h % SYM_MAX_HASH;
  63. }
  64.  
  65.  
  66. /* Search the list of symbols <list> for the symbol <name>.
  67.  * Return a pointer to the symbol or NULL if not found.
  68.  */
  69. static Symbol *
  70. search_symbol_list (list, name)
  71. Symbol *list;
  72. char *name;
  73. {
  74.     Symbol *sym;
  75.  
  76.     for (sym = list; sym != NULL; sym = sym->next) {
  77.     if (strcmp(sym->name, name) == 0)
  78.         return sym;
  79.     }
  80.     return NULL;
  81. }
  82.  
  83.  
  84. /* Look for symbol <name> in symbol table <symtab>.
  85.  * Return a pointer to the symbol or NULL if not found.
  86.  */
  87. Symbol *
  88. find_symbol (symtab, name)
  89. SymbolTable *symtab;
  90. char *name;
  91. {
  92.     return search_symbol_list(symtab->bucket[hash(name)], name);
  93. }
  94.  
  95.  
  96. /* If the symbol <name> does not already exist in symbol table <symtab>,
  97.  * then add the symbol to the symbol table.
  98.  * Return a pointer to the symbol.
  99.  */
  100. Symbol *
  101. new_symbol (symtab, name, value, flags)
  102. SymbolTable *symtab;    /* symbol table */
  103. char *name;        /* symbol name */
  104. char *value;        /* symbol value */
  105. int flags;        /* symbol attributes */
  106. {
  107.     Symbol *sym;
  108.     int i;
  109.  
  110.     if ((sym = find_symbol(symtab, name)) == NULL) {
  111.     sym = (Symbol *)xmalloc(sizeof(Symbol));
  112.     sym->name = xstrdup(name);
  113.     i = hash(name);
  114.     sym->next = symtab->bucket[i];
  115.     symtab->bucket[i] = sym;
  116.     } else {
  117.     free(sym->value);
  118.     }
  119.     sym->value = (value != NULL) ? xstrdup(value) : NULL;
  120.     sym->flags = flags;
  121.     return sym;
  122. }
  123.